//! Call pattern protocol definitions for homeserver identity services.

use aspect_codec::prelude::*;
use aspect_ident::{DeviceIdent, DirPackage};

/// Protocol definition for device identity RPC.
pub struct DeviceDbProto;

/// Request devices by some key.
#[derive(Clone, Debug)]
pub enum QueryRequest {
    /// Request by device ID.
    Id(DeviceIdent),

    /// Request all devices in the database.
    Dump(()),

    /// Request by username.
    User(String),
}

aspect_codec::inst_enum_codec! {
    QueryRequest u8 {
        0 => Id(field DeviceIdent),
        1 => Dump(field ()),
        2 => User(field String),
    }
}

/// Devices that match the key.
#[derive(Clone, Debug)]
pub struct QueryResponse {
    pub devices: Vec<DirPackage>,
}

impl QueryResponse {
    pub fn new(devices: Vec<DirPackage>) -> Self {
        Self { devices }
    }
}

aspect_codec::inst_semimanual_codec! {
    QueryResponse {
        devices vec DirPackage,
    }
}

/// Protocol definition for device announcement RPC.
pub struct DeviceAnnProto;

#[derive(Clone, Debug)]
pub struct AnnRequest {
    package: DirPackage,
}

impl AnnRequest {
    pub fn new(package: DirPackage) -> Self {
        Self { package }
    }

    pub fn package(&self) -> &DirPackage {
        &self.package
    }

    pub fn into_package(self) -> DirPackage {
        self.package
    }
}

aspect_codec::inst_struct_codec! {
    AnnRequest {
        package: DirPackage,
    }
}

#[derive(Clone, Debug)]
pub enum AnnResponse {
    /// Package accepted.
    Accepted(()),

    /// Package rejected with some rejection string.
    Rejected(String),
}

aspect_codec::inst_enum_codec! {
    AnnResponse u8 {
        0 => Accepted(field ()),
        1 => Rejected(field String),
    }
}
